#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
struct student
{
	long myype;//消息类型
	char mtsxt[128];//正文
};
#define size (sizeof(struct student)-sizeof(long))
int main(int argc,const char*argv[])
{
	//创建子进程
	pid_t pid=fork();
	if(pid>0)
	{
		//父进程
		//获取文件键值
		key_t key=ftok(argv[2],1);
		if(key==-1){perror("获取key失败");return -1;}
		//创建消息队列
		int p;
		if((p=msgget(key,IPC_CREAT|IPC_EXCL|0664))!=-1)
			perror("创建消息队列成功");
		else if((p=msgget(key,IPC_CREAT))!=-1)
			perror("打开消息队列成功");
		else
		{
			perror("失败失败");
			return -1;
		}
		//声明结构体变量
		struct student t1;
		int t;
		while(1)
		{
			printf("请输入消息类型");
			scanf("%ld",&t1.myype);
			getchar();
			printf("请输入信息：");
			fgets(t1.mtsxt,size,stdin);
			t1.mtsxt[strlen(t1.mtsxt)-1]='\0';
			if(msgsnd(p,&t1,size,0)==-1){perror("写入失败");return -1;}
			else
			{
				printf("发送成功%s\n",t1.mtsxt);
			}
			if(strcmp(t1.mtsxt,"q")==0)
				break;
		}
		//退出进程
		exit(0);

		//回收子进程
		printf("等待回收子进程1\n");
		waitpid(0,NULL,0);
	}
	else if(pid==0)
	{
		//子进程
		//获取文件键值
		key_t key=ftok(argv[1],1);
		if(key==-1){perror("获取key失败");return -1;}
		//创建消息队列
		int p;
		if((p=msgget(key,IPC_CREAT|IPC_EXCL|0664))!=-1)
		if((p=msgget(key,IPC_CREAT|IPC_EXCL|0664))!=-1)
			perror("创建消息队列成功");
		else if((p=msgget(key,IPC_CREAT))!=-1)
			perror("打开消息队列成功");
		else
		{
			perror("失败失败");
			return -1;
		}
		//声明结构体变量
		struct student t1;
		int t;
		while(1)
		{
			if(msgrcv(p,&t1,size,0,0)==-1){perror("读取失败");return -1;}
			else
				printf("接收成功%s\n",t1.mtsxt);
			if(strcmp(t1.mtsxt,"q")==0)
				break;
		}
		//退出进程
		exit(0);
	}
	else
	{
		perror("创建失败");
		return -1;
	}
	return 0;
}
